import type { BodyInit } from '@cloudflare/workers-types/2023-07-01/index';
import { mergeHeaders } from '@zenstone/ts-utils/http';
import {
  isNumber,
  isNumberVal,
  limitNumberMinMax
} from '@zenstone/ts-utils/number';
import { isInferObj } from '@zenstone/ts-utils/object';

export const createResp = (commonHeaders?: [string, string][]) => {
  const json = (
    data: BodyInit | null,
    statusOrHeaders?: number | HeadersInit,
    statusCode?: number,
  ) => {
    let status: number | undefined;
    const headers: HeadersInit = [
      ...(commonHeaders ?? []),
      ['content-type', 'application/json'],
    ];
    let userHeaders: HeadersInit | undefined;
    if (statusOrHeaders != null) {
      if (isNumber(statusOrHeaders)) {
        status = statusOrHeaders;
      } else {
        userHeaders = statusOrHeaders;
        status = statusCode;
      }
    }

    // @ts-ignore
    return new Response(data, {
      status,
      headers: mergeHeaders(headers, userHeaders),
    });
  };

  json.stringify = (
    data: unknown,
    statusOrHeaders?: number | HeadersInit,
    status?: number,
  ) => json(JSON.stringify(data), statusOrHeaders, status);

  return {
    json,
  };
};

export const statusCode = (err: unknown) => {
  if (isInferObj(err, (it) => isNumberVal(it.statusCode))) {
    return limitNumberMinMax(err.statusCode, 100, 599);
  }
  return 500;
};

export const removeExtname = (path: string) =>
  path.replace(/\.(d.ts|[^\.]+)$/gm, '');
